package com.dubito.gallery

import android.Manifest
import android.os.Build
import android.os.Bundle
import android.view.WindowManager
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Button
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.runtime.staticCompositionLocalOf
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsControllerCompat
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavController
import androidx.navigation.NavType
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import androidx.navigation.navArgument
import com.dubito.gallery.data.ColorThemeSettings
import com.dubito.gallery.data.DarkThemeSettings
import com.dubito.gallery.ui.gallery.GalleryScreen
import com.dubito.gallery.ui.gallery.GalleryScreenEvent
import com.dubito.gallery.ui.gallery.ViewerScreen
import com.dubito.gallery.ui.settings.SettingsFolderScreen
import com.dubito.gallery.ui.settings.SettingsScreen
import com.dubito.gallery.ui.theme.GalleryTheme
import com.google.accompanist.permissions.ExperimentalPermissionsApi
import com.google.accompanist.permissions.isGranted
import com.google.accompanist.permissions.rememberPermissionState
import com.google.accompanist.permissions.shouldShowRationale

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        WindowCompat.setDecorFitsSystemWindows(window, false)
        WindowInsetsControllerCompat(window, window.decorView).systemBarsBehavior =
            WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            window.attributes.layoutInDisplayCutoutMode =
                WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
        }
        window.statusBarColor = android.graphics.Color.TRANSPARENT
        setContent {
            val viewModel = viewModel<MainViewModel>()
            val uiState by viewModel.uiState.collectAsState()
            AppScreen(uiState = uiState)
        }
    }
}

@Composable
fun AppScreen(uiState: MainUiState) {
    when (uiState) {
        is MainUiState.Loading -> {}
        is MainUiState.Success -> {
            val isDark = when (uiState.darkTheme) {
                DarkThemeSettings.Off -> false
                DarkThemeSettings.On -> true
                DarkThemeSettings.UseSystemSettings -> isSystemInDarkTheme()
            }
            val isDynamicColor = uiState.colorTheme == ColorThemeSettings.Wallpaper
            GalleryTheme(isDark, isDynamicColor) {
                Surface(color = MaterialTheme.colorScheme.background) {
                    AppContent()
                }
            }
        }
    }
}

val LocalNavController = staticCompositionLocalOf<NavController> { error("No NavController") }

@OptIn(ExperimentalPermissionsApi::class)
@Composable
fun AppContent() {
    var permissionRequested by rememberSaveable { mutableStateOf(false) }
    val ps = rememberPermissionState(permission = Manifest.permission.READ_EXTERNAL_STORAGE) {
        permissionRequested = true
    }
    when {
        ps.status.isGranted -> {
            AppNavigation()
        }
        ps.status.shouldShowRationale -> RequestPermission(shouldShowRationale = true) {
            ps.launchPermissionRequest()
        }
        permissionRequested -> {
            AskPermissionInSettingApp()
        }
        else -> RequestPermission(shouldShowRationale = false) {
            ps.launchPermissionRequest()
        }
    }
}

@Composable
fun AppNavigation() {
    val navController = rememberNavController()
    CompositionLocalProvider(LocalNavController provides navController) {
        NavHost(navController = navController, startDestination = "gallery") {
            composable(route = "gallery") {
                GalleryScreen(
                    onItemSelected = { index -> navController.navigate("viewer/$index") },
                    onEvent = { event ->
                        when (event) {
                            GalleryScreenEvent.SelectSettings ->
                                navController.navigate("settings")
                        }
                    }
                )
            }
            composable(
                route = "viewer/{index}",
                arguments = listOf(navArgument(name = "index") { type = NavType.IntType })
            ) { backStackEntry ->
                val index = backStackEntry.arguments?.getInt("index") ?: 0
                ViewerScreen(index = index)
            }
            composable(route = "settings") {
                SettingsScreen()
            }
            composable(route = "settings_folder") {
                SettingsFolderScreen()
            }
        }
    }
}

@Composable
fun RequestPermission(shouldShowRationale: Boolean, onClick: () -> Unit) {
    Column(
        modifier = Modifier.fillMaxSize(),
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center
    ) {
        val text = if (shouldShowRationale) {
            stringResource(id = R.string.rationale_permission)
        } else {
            stringResource(id = R.string.request_permission)
        }
        Text(text = text, modifier = Modifier.padding(20.dp))
        Button(onClick = onClick) {
            Text(text = stringResource(id = R.string.button_continue))
        }
    }
}

@Composable
fun AskPermissionInSettingApp() {
    Box(
        modifier = Modifier.fillMaxSize(),
        contentAlignment = Alignment.Center
    ) {
        Text(
            text = stringResource(id = R.string.request_to_grant_permission),
            modifier = Modifier.padding(20.dp)
        )
    }
}
